Analysis of the AGILE Scientific Ratemeters¶

The AGILE Scientific Ratemeter files contain the photon counts recorded by every AGILE instrument:

  • The Gamma-Ray Imaging Detector (GRID), with photon energy >50 MeV.
  • The Mini-Calorimeter (MCAL), energy band [0.4 - 100] MeV.
  • The SuperAGILE (SA), energy band [18 - 60] keV.
  • The 5 panels of the Anti-Coincidence System:
    • The Top panel (AC0), energy band [50 - 200] keV.
    • The 4 lateral panels (AC1, AC2, AC3, AC4), energy band [80 - 200] keV.

The counts recorded are integrated in the energy range of the detector and in time bins of fixed width of 1.024 s, with the exception of the SuperAGILE ratemeters which use bins of 0.512 s.

The ratemeter files (the so-called "3913" files) are provided in a compressed FITS Format optimized for data download from the satellite. One file was produced for every satellite contact.

Agilepy implements a AGRatemeters class that reads the ratemeters files and extract the Ratemeters Light Curves. The Light Curves can be used to check for transient phenomena, and if the Burst Onest Time (T0) of a Burst is provided, the significance and duration of the Burst can be estimated.

The Analysis of the Scientific Ratemeters follows these general steps:

  1. Prepare a YAML configuration file for AGRatemeters. You can do it manually or by using AGRatemeters.getConfiguration().
  2. Define a AGRatemeters object, and read the 3913 file with AGRatemeters.readRatemeters().
  3. You can plot the Light Curve with the AGRatemeters.plotRatemeters() function, perform a simple Aperture Photometry analysis with AGRatemeters.analyseSignal(), perform a basic estimation of the burst duration with AGRatemeters.estimateDuration().

In this notebook, we show examples for two GRBs.

Note: each instrument is pointed in a different direction. In particular, AC4 is always pointed towards the Sun.

In [1]:
# Import the relevant classes
import agilepy

from agilepy.api.AGRatemeters import AGRatemeters

Example 1: GRB 221028A¶

In [2]:
# Prepare the YAML Configuration File.
# You can create it manually or use AGRatemeters.getConfiguration()

outputDir1    = "/home/flareadvocate/workspace/shared_dir/"
confFilePath1 = "/home/flareadvocate/workspace/shared_dir/tutorial_rm_GRB221018A.yaml"

AGRatemeters.getConfiguration(
    confFilePath=confFilePath1,
    outputDir=outputDir1,
    userName="my-name",
    sourceName="rm-source",
    verboselvl=0,
    filePath="$AGILE/agilepy-test-data/ratemeters/PKP080686_1_3913_000.lv1.cor.gz",
    timetype="isot",
    T0="2022-10-28T13:16:27",
    background_tmin=-50.0,
    background_tmax=-20.0,
    signal_tmin=-1.0,
    signal_tmax=3.0
    )

The YAML file has the following sections and field:

  • output: common to all agilepy classes, sets the output fields.
  • selection: includes one argument used to read the data:
    • filePath: path to the input file.
  • analysis: includes arguments for plots and further analyses:
    • timetype and T0: Format and value of the Burst Oneset Time. It can be TT or OBT for AGILE seconds (TT seconds since 2004-01-01 00:00:00.000), or a format acknowledged by the astropy.time.Time class. T0 will be converted in AGILE seconds and used as reference time for plots and analyses.
    • background_tmin and background_tmax: time range used for evaluation of the background, in seconds with respect to T0.
    • signal_tmin and signal_tmax: time range used for evaluation of the signal, in seconds with respect to T0.
In [3]:
# Create the AGRatemeters object
ag_rm1 = AGRatemeters(confFilePath1)
Log level set to WARNING and output to /home/flareadvocate/workspace/shared_dir/my-name_rm-source_20250811-211100/logs
In [4]:
# You can Use the setOptions() method to change the configuration, e.g.:
ag_rm1.setOptions(background_tmin=-50.0, background_tmax=-10.0)

# Check configuration.
ag_rm1.printOptions()
{ 'analysis': { 'T0': 594047787.0,
                'background_tmax': -10.0,
                'background_tmin': -50.0,
                'signal_tmax': 3.0,
                'signal_tmin': -1.0,
                'timetype': 'TT'},
  'output': { 'filenameprefix': 'ratemeters_product',
              'outdir': PosixPath('/home/flareadvocate/workspace/shared_dir/my-name_rm-source_20250811-211100'),
              'sourcename': 'rm-source',
              'username': 'my-name',
              'verboselvl': 0},
  'selection': { 'file_path': '/home/flareadvocate/agiletools/agilepy-test-data/ratemeters/PKP080686_1_3913_000.lv1.cor.gz'}}

Read the Ratemeters with AGRatemeters.readRatemeters(writeFiles). Optional aguments are:

  • filePath: if None (default), it will be read from the configuration. Otherwise, the function will read the file from the path provided explicitly.
  • writeFiles: if True (default), write the Light Curves as .txt files.

The method will return a dictionary of tables, one per instrument, with the ratemeter Light Curve. They can be accessed using the instrument name as a key. The tables can also be accessed via the AGRatemeters.ratemetersTables property.

Each Table has 3 columns:

  • OBT: detection time in AGILE seconds
  • COUNTS: counts measured
  • COUNTS_D: counts de-trended with a FFT algorithm to remove background modulation due to the orbital motion and spinning of the satellite.
In [5]:
# Read the ratemeter file
ratemeters_tables = ag_rm1.readRatemeters()
/home/flareadvocate/Agilepy/agilepy/api/AGRatemeters.py:130: RuntimeWarning: divide by zero encountered in scalar divide
  data_yf = (2 / np.sum(values)) * abs(scipy.fftpack.fft(values))**2 #* scipy.fftpack.rfft(y)
/home/flareadvocate/Agilepy/agilepy/api/AGRatemeters.py:130: RuntimeWarning: invalid value encountered in multiply
  data_yf = (2 / np.sum(values)) * abs(scipy.fftpack.fft(values))**2 #* scipy.fftpack.rfft(y)
In [6]:
# The Light Curves are stored in Tables, and can be accessed via Dictionary
print(ratemeters_tables.keys())

# E.g. access the AC Top table
display(ratemeters_tables['AC0'])

# The Dictionary can be accessed also via property
display(ag_rm1.ratemetersTables['MCAL'])
dict_keys(['GRID', 'MCAL', 'SA', 'AC0', 'AC1', 'AC2', 'AC3', 'AC4'])
Table length=4528
OBTCOUNTSCOUNTS_D
float64int32float64
594047441.60220829263156.8248533042997
594047442.626208128873124.333154382883
594047443.65020830083251.9585105203537
594047444.67420831163366.699623659409
594047445.69820831773434.5546431971634
594047446.72220828483112.521122809405
594047447.746208131303401.5959827584365
594047448.77020831093387.775478156238
.........
594053444.71491231543336.9875599624684
594053445.738912132253413.561361842546
594053446.76291234223616.249256148664
594053447.786912133883588.0523412390567
594053448.81091233423547.9716359251147
594053449.834912130853297.0080139731317
594053450.858912133063524.1621390686196
594053451.88291232203444.434400936505
Table length=4528
OBTCOUNTSCOUNTS_D
float64int64float64
594047441.60220812181180.354681306513
594047442.626208112621224.5227916500485
594047443.65020812741236.7284040401562
594047444.67420812481210.9728004749263
594047445.69820812571220.2571625405335
594047446.72220811941157.582555424022
594047447.746208111681131.949912832763
594047448.77020811861150.3600229896524
.........
594053444.71491212781240.1864978404471
594053445.738912112461208.1071081434036
594053446.76291211961158.053424459286
594053447.786912111781140.0269074512476
594053448.81091212311193.0290561221693
594053449.834912112301192.0613911318853
594053450.858912111661128.1254375638737
594053451.88291212341196.2227073174276

Plot the Ratemeters with AGRatemeters.plotRatemeters(). The function has the following arguments:

  • plotRange: time limits of the plot in seconds with respect to T0.
  • useDetrendedData: if True, use the De-trended counts, if False the raw counts.
  • plotInstruments: list of instruments to plot in asingle plot. Possible values are "AC0","AC1","AC2","AC3","AC4","MCAL","GRID","SA".
    • Additionally, including "2RM" in the list will make a separate plot with AC0 and MCAL. "3RM" will make a separate plot with AC0, MCAL, SA. "8RM" will make a separate plot with all the ratemeters.
In [7]:
# Plot the Ratemeters
plots = ag_rm1.plotRatemeters(plotRange=(-100,100), useDetrendedData=True, plotInstruments=["3RM","GRID","AC4"])
# This combination will produce two plots:
# the "3RM" (SA, AC0, MCAL) + one with the instruments lsited explicitly (AC0, MCAL)

# It returns the List of Plots saved.
print(plots)
[PosixPath('/home/flareadvocate/workspace/shared_dir/my-name_rm-source_20250811-211100/plots/ratemeters_D_3RM.png'), PosixPath('/home/flareadvocate/workspace/shared_dir/my-name_rm-source_20250811-211100/plots/ratemeters_D_GRID_AC4.png')]
In [8]:
# The Raw Data can show the Orbital Modulation of the Background of each detector
# Due to the satellite motion and spinning
plots = ag_rm1.plotRatemeters(plotRange=(-200,200), useDetrendedData=False, plotInstruments=["2RM"])

# List of Plots
print(plots)
[PosixPath('/home/flareadvocate/workspace/shared_dir/my-name_rm-source_20250811-211100/plots/ratemeters_ND_2RM.png')]

A simple Aperture photometry analysis can be performed with AGRatemeters.analyseSignal() Optional arguments (with default values shown) are:

  • backgroundRange=(None,None): Time Range for Background Estimation. If None, they are read from the configuration.
  • signalRange=(None,None): Time Range for Signal Estimation. If None, they are read from the configuration.
  • useDetrendedData=True: boolean flag for the de-trended data.

The method returns a table with the number of counts recorded in the Signal and Background intervals (ON and OFF), the duration of the intervals (which are always multiples of 0.512s for SuperAGILE and 1.024s for the other detectors), the estimation of the Background Rate in cts/s and the Li&Ma Significance.

In [9]:
results = ag_rm1.analyseSignal(backgroundRange=(-20,-15), signalRange=(-1,3), useDetrendedData=True)
display(results)
Table length=8
instrumentt_ONN_ONt_OFFN_OFFR_BKGlima
str4float64int64float64int64float64float64
GRID3.072475844.2016550815593.431.11
MCAL3.07255194.20158301387.76513.712
SA3.58404.71300.00.0
AC03.072142634.201167723992.38313.22
AC13.072124684.201144613442.27613.442
AC23.072125924.201143293410.85515.005
AC33.072100434.201120162860.2719.861
AC43.072121834.201149443557.2488.889

A simple estimation of the Duration of the Burst can be performed with AGRatemeters.estimateDuration(). Its arguments are (with default values shown) are:

  • dataRange: Time Range for the Plot. Must include Background and Signal.
  • backgroundRange=(None,None): Time Range for Background Estimation. If None, they are read from the configuration.
  • signalRange=(None,None): Time Range for Signal Estimation. If None, they are read from the configuration.
  • useDetrendedData=True: boolean flag for the de-trended data.
  • plotDuration: If True, plot the Differential and Cumulative, Background-subtracted Light Curves.

The plot include the Background-subtracted, differential and Cumulative Light Curves of SA, MCAL, AC0 (if activated). The red (blue) bands identify the background (signal) range, and the green lines the region where the signal is significantly rising.

In [10]:
results, plot = ag_rm1.estimateDuration(dataRange=(-50,50),backgroundRange=(-50,-10),signalRange=(-1,3),useDetrendedData=False)

# The result is a dictionary for every instrument.
# For every instrument, the arrays of counts are recorded, and also an estimate of the duration
results_mcal = results['MCAL']
print(results_mcal.keys())
print(f"Burst duration estimated from MCAL: {results_mcal['duration']:.4g}s")
results_ac0 = results['AC0']
print(f"Burst duration estimated from AC0: {results_ac0['duration']:.4g}s")

# Path of the saved Image
print(plot)
2025-08-11 21:11:11 | WARNING  | agilepy.api.AGRatemeters.AGRatemeters | Detector SA not active. | (AGRatemeters.py:1321)
dict_keys(['time', 'counts', 'counts_bkgsub', 'integral_counts', 'sigrise_time', 'duration'])
Burst duration estimated from MCAL: 3.072s
Burst duration estimated from AC0: 1.024s
/home/flareadvocate/workspace/shared_dir/my-name_rm-source_20250811-211100/plots/ratemeters_duration_ND.png

Example: GRB 231129C¶

In [11]:
# Configuration
outputDir2    = "/home/flareadvocate/workspace/shared_dir/"
confFilePath2 = "/home/flareadvocate/workspace/shared_dir/tutorial_rm_GRB231129C.yaml"

AGRatemeters.getConfiguration(
    confFilePath=confFilePath2,
    outputDir=outputDir2,
    userName="my-name",
    sourceName="rm-source",
    verboselvl=0,
    filePath="$AGILE/agilepy-test-data/ratemeters/PKP086465_1_3913_000.lv1.cor.gz",
    timetype="isot",
    T0="2023-11-29T19:10:18",
    background_tmin=-50.0,
    background_tmax=-25.0,
    signal_tmin=-2.0,
    signal_tmax=10.0
    )
In [12]:
# Create the AGRatemeters object
ag_rm2 = AGRatemeters(confFilePath2)

# Check Options
ag_rm2.printOptions()
Log level set to WARNING and output to /home/flareadvocate/workspace/shared_dir/my-name_rm-source_20250811-211111/logs
{ 'analysis': { 'T0': 628369818.0,
                'background_tmax': -25.0,
                'background_tmin': -50.0,
                'signal_tmax': 10.0,
                'signal_tmin': -2.0,
                'timetype': 'TT'},
  'output': { 'filenameprefix': 'ratemeters_product',
              'outdir': PosixPath('/home/flareadvocate/workspace/shared_dir/my-name_rm-source_20250811-211111'),
              'sourcename': 'rm-source',
              'username': 'my-name',
              'verboselvl': 0},
  'selection': { 'file_path': '/home/flareadvocate/agiletools/agilepy-test-data/ratemeters/PKP086465_1_3913_000.lv1.cor.gz'}}
In [13]:
# Read ratemeters
ratemeters = ag_rm2.readRatemeters()
/home/flareadvocate/Agilepy/agilepy/api/AGRatemeters.py:130: RuntimeWarning:

divide by zero encountered in scalar divide

/home/flareadvocate/Agilepy/agilepy/api/AGRatemeters.py:130: RuntimeWarning:

invalid value encountered in multiply

In [14]:
# Plot Light Curves
plots = ag_rm2.plotRatemeters(plotRange=(-60,60), useDetrendedData=True, plotInstruments=["2RM"])
print(plots)
[PosixPath('/home/flareadvocate/workspace/shared_dir/my-name_rm-source_20250811-211111/plots/ratemeters_D_2RM.png')]
In [15]:
# Aperture Photometry
results = ag_rm2.analyseSignal(useDetrendedData=True)
display(results)
Table length=8
instrumentt_ONN_ONt_OFFN_OFFR_BKGlima
str4float64int64float64int64float64float64
GRID10.24517072223.56634019914436.0147.991
MCAL10.2451506923.566275781170.24522.299
SA11.269024.5900.00.0
AC010.2454643323.566727093085.33563.654
AC110.2453631923.566677972876.89931.756
AC210.2453423423.566642512726.42830.069
AC310.2453111823.566536032274.59140.004
AC410.2454241723.566698962965.96853.355
In [16]:
# Estimate Duration
result_dict, plot = ag_rm2.estimateDuration(dataRange=(-60,60), useDetrendedData=False)

print(f"Burst duration estimated from MCAL: {result_dict['MCAL']['duration']:.4g}s")
2025-08-11 21:11:25 | WARNING  | agilepy.api.AGRatemeters.AGRatemeters | Detector SA not active. | (AGRatemeters.py:1321)
Burst duration estimated from MCAL: 9.221s
In [ ]: